package cmd

import (
	"github.com/carapace-sh/carapace"
	"github.com/carapace-sh/carapace-bin/completers/kubeadm_completer/cmd/action"
	"github.com/spf13/cobra"
)

var initCmd = &cobra.Command{
	Use:   "init",
	Short: "Run this command in order to set up the Kubernetes control plane",
	Run:   func(cmd *cobra.Command, args []string) {},
}

func init() {
	carapace.Gen(initCmd).Standalone()
	initCmd.Flags().String("apiserver-advertise-address", "", "The IP address the API Server will advertise it's listening on. If not set the default network interface will be used.")
	initCmd.Flags().Int32("apiserver-bind-port", 6443, "Port for the API Server to bind to.")
	initCmd.Flags().StringSlice("apiserver-cert-extra-sans", []string{}, "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.")
	initCmd.Flags().String("cert-dir", "/etc/kubernetes/pki", "The path where to save and store the certificates.")
	initCmd.Flags().String("certificate-key", "", "Key used to encrypt the control-plane certificates in the kubeadm-certs Secret.")
	initCmd.Flags().String("config", "", "Path to a kubeadm configuration file.")
	initCmd.Flags().String("control-plane-endpoint", "", "Specify a stable IP address or DNS name for the control plane.")
	initCmd.Flags().String("cri-socket", "", "Path to the CRI socket to connect. If empty kubeadm will try to auto-detect this value; use this option only if you have more than one CRI installed or if you have non-standard CRI socket.")
	initCmd.Flags().Bool("dry-run", false, "Don't apply any changes; just output what would be done.")
	initCmd.Flags().String("feature-gates", "", "A set of key=value pairs that describe feature gates for various features.")
	initCmd.Flags().StringSlice("ignore-preflight-errors", []string{}, "A list of checks whose errors will be shown as warnings. Example: 'IsPrivilegedUser,Swap'. Value 'all' ignores errors from all checks.")
	initCmd.Flags().String("image-repository", "k8s.gcr.io", "Choose a container registry to pull control plane images from")
	initCmd.Flags().String("kubernetes-version", "stable-1", "Choose a specific Kubernetes version for the control plane.")
	initCmd.Flags().String("node-name", "", "Specify the node name.")
	initCmd.Flags().String("patches", "", "Path to a directory that contains files named \"target[suffix][+patchtype].extension\".")
	initCmd.Flags().String("pod-network-cidr", "", "Specify range of IP addresses for the pod network.")
	initCmd.Flags().String("service-cidr", "10.96.0.0/12", "Use alternative range of IP address for service VIPs.")
	initCmd.Flags().String("service-dns-domain", "cluster.local", "Use alternative domain for services, e.g. \"myorg.internal\".")
	initCmd.Flags().Bool("skip-certificate-key-print", false, "Don't print the key used to encrypt the control-plane certificates.")
	initCmd.Flags().StringSlice("skip-phases", []string{}, "List of phases to be skipped")
	initCmd.Flags().Bool("skip-token-print", false, "Skip printing of the default bootstrap token generated by 'kubeadm init'.")
	initCmd.Flags().String("token", "", "The token to use for establishing bidirectional trust between nodes and control-plane nodes.")
	initCmd.Flags().String("token-ttl", "", "The duration before the token is automatically deleted (e.g. 1s, 2m, 3h). If set to '0', the token will never expire")
	initCmd.Flags().Bool("upload-certs", false, "Upload control-plane certificates to the kubeadm-certs Secret.")
	rootCmd.AddCommand(initCmd)

	carapace.Gen(initCmd).FlagCompletion(carapace.ActionMap{
		"cert-dir":                carapace.ActionDirectories(),
		"certificate-key":         carapace.ActionFiles(),
		"config":                  carapace.ActionFiles(),
		"cri-socket":              carapace.ActionFiles(),
		"ignore-preflight-errors": action.ActionChecks().UniqueList(","),
		"patches":                 carapace.ActionDirectories(),
		"skip-phases": carapace.ActionMultiParts(",", func(c carapace.Context) carapace.Action {
			return action.ActionPhases().Invoke(c).Filter(c.Parts...).ToMultiPartsA("/").NoSpace() // TODO user UniqueList("/")
		}),
	})
}
